﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Globalization;

using System.Numerics;

using NumDouble = MathNet.Numerics.LinearAlgebra.Double;
using NumComplex = MathNet.Numerics.LinearAlgebra.Complex;

namespace Estimador_EDAL.Estimador
{
    public class CEstadoEsperado
    {
        private List<CEstado> m_ListEstado;

        #region Construção do Objeto

        public CEstadoEsperado()
        {
            Defaults();
        }

        public CEstadoEsperado(CEstadoEsperado medElet)
        {
            Copy(medElet);
        }

        public CEstadoEsperado(List<CEstado> listEstado)
        {
            m_ListEstado = listEstado;
        }

        private void Defaults()
        {
            m_ListEstado = new List<CEstado>();
        }

        private void Copy(CEstadoEsperado estEsperado)
        {
            m_ListEstado.Clear();
            foreach (CEstado est in estEsperado.m_ListEstado)
                m_ListEstado.Add(new CEstado(est));
        }

        public string ValidaDados(bool isReportZerado)
        {
            //falta implementar!!!!!!!!!!!!!!!!!!!!!!!
            return "";
        }

        #endregion Construção do Objeto

        #region Get's e Set's

        public ReadOnlyCollection<CEstado> ListEstado
        {
            get
            {
                return m_ListEstado.AsReadOnly();
            }
        }

        #endregion Get's e Set's

        #region Rotinas Públicas - Add e Remove CEstado

        public bool AddEstado(CEstado est)
        {
            bool achou = m_ListEstado.Contains(est);
            if (achou)
                return false;

            m_ListEstado.Add(est);
            return true;
        }

        public bool RemoveMedicao(CEstado est)
        {
            bool achou = m_ListEstado.Contains(est);
            if (!achou)
                return false;

            m_ListEstado.Remove(est);
            return true;
        }

        #endregion Rotinas Públicas - Add e Remove CMedicao

        #region Rotinas Públicas - DE e PARA formato texto

        public void CarregaDeTxt(string str)
        {
            string[] str_Partes = str.Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (string str_Est in str_Partes)
            {
                string str_Est_Tmp = str_Est.Trim();
                if (str_Est_Tmp.StartsWith("("))
                    continue;

                CEstado estado = new CEstado();
                estado.CarregaDeTxt(str_Est);
                m_ListEstado.Add(estado);
            }
        }

        public string DescarregaParaTxt(bool isReportZerado)
        {
            string ret = (isReportZerado) ? "\n\n" : "";

            ret += "Lista com Estado Esperado:\n\n";

            foreach (CEstado est in m_ListEstado)
                ret += est.DescarregaParaTxt() + "\n";

            return ret;
        }

        #endregion

        #region Rotinas Públicas - Fornece estado esperado

        public NumDouble.DenseVector Atualiza_X(CRedeElet redeElet)
        {
            int nroBarr = m_ListEstado.Count;
            NumDouble.DenseVector xesp = new NumDouble.DenseVector(2 * nroBarr - 1, 0.0);

            for (int i = 0; i < nroBarr; i++)
            {
                uint barra = m_ListEstado[i].Barra;
                int pos = redeElet.ListBarr.IndexOf(barra);

                if(pos > 0) xesp[pos-1] = m_ListEstado[i].Vpu.Phase;
                xesp[pos-1+nroBarr] = m_ListEstado[i].Vpu.Magnitude;
            }

            return xesp;
        }

        #endregion Rotinas Públicas - Fornece estado esperado
    }
}
